/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.formmetadata.metadataanalysis;

import com.inspur.edp.lcm.metadata.api.entity.FrameWorkTypeEnum;
import com.inspur.edp.web.common.customexception.WebCustomException;
import com.inspur.edp.web.common.environment.ExecuteEnvironment;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.common.serialize.SerializeUtility;
import com.inspur.edp.web.common.utility.StringUtility;
import com.inspur.edp.web.formmetadata.constant.I18nExceptionConstant;
import com.inspur.edp.web.formmetadata.metadata.formdom.FormDOM;
import com.inspur.edp.web.formmetadata.metadataanalysis.form.AnalysisExternalComponentResult;
import com.inspur.edp.web.formmetadata.metadatamanager.FormMetadataManager;

import java.util.HashMap;

/**
 * 表单数据解析
 *
 * @author noah
 */
public class FormAnalysis extends AbstractMetadataAnalysis {

    public FormAnalysis(ExecuteEnvironment executeEnvironment, boolean isUpgradeTool) {
        super(executeEnvironment, isUpgradeTool);
    }

    /**
     * 解析表单元数据
     */
    public ResolveFormResult resolveForm(String formMetadataFileName, String formMetadataFilePath, String destStoragePath, String projectPath) {
        // Get Visual Dom
        FormMetadataManager formMetadataManager = new FormMetadataManager(this.executeEnvironment, null, this.isUpgradeTool);
        String formDom = formMetadataManager.getVisualDom(formMetadataFileName, formMetadataFilePath);

        // 反序列化表单元数据
        FormDOM json = SerializeUtility.getInstance().deserialize(formDom, FormDOM.class);

        if (!json.getOptions().isEnableFormJieXi()) {
            formMetadataManager.saveMetadataFile(destStoragePath, formMetadataFileName.toLowerCase() + ".json", formDom);

            FrameWorkTypeEnum frameWorkTypeEnum = formMetadataManager.getFrameWorkTypeEnum(formMetadataFileName, formMetadataFilePath);
            if(frameWorkTypeEnum == FrameWorkTypeEnum.Vue){
                String formCode = json.getModule().getCode().toLowerCase();
                this.generateStylesFile(destStoragePath, formCode, json);
            }
        }


        return new ResolveFormResult(json, formMetadataManager.getRelativePath());
    }

    public void generateStylesFile( String destStoragePath , String formCode, FormDOM formJson){
        FormMetadataManager formMetadataManager = new FormMetadataManager(this.executeEnvironment, null, this.isUpgradeTool);
        String scssFileName = formCode + ".scss";
        String customClassText = this.analysisCustomClass(formJson);
        String customClassPath = FileUtility.combine(destStoragePath, "styles", formCode);

        formMetadataManager.saveMetadataFile(customClassPath, scssFileName, customClassText);
    }

    public String analysisCustomClass(FormDOM formJson) {
        if(formJson == null || formJson.getModule() == null || formJson.getModule().getCustomClass() == null){
            return "";
        }

        //找到元数据的自定义样式
        HashMap<String, String> customClass = formJson.getModule().getCustomClass();
        //搞到表单code
        String formCode = formJson.getModule().getCode();
        StringBuilder stringBuilder = new StringBuilder();

        for(String key : customClass.keySet()){
            String customClassText = customClass.get(key);
            String text = "div." + key  + "[scope-" + formCode + "] { " + customClassText +" } ";
            stringBuilder.append(text);
        }

        return stringBuilder.toString();
    }

    /**
     * 定义ResolveForm 方法的执行返回结果，使用静态内部类
     * 进行参数返回值封装
     */
    public static class ResolveFormResult {
        private final FormDOM json;
        private final String relativePath;

        public ResolveFormResult(FormDOM json, String relativePath) {
            this.json = json;
            this.relativePath = relativePath;
        }

        public FormDOM getJson() {
            return this.json;
        }

        public String getRelativePath() {
            return this.relativePath;
        }

    }

    /// <summary>
    /// 分析扩展组件
    /// </summary>
    /// <param name="virtualDom"></param>
    public AnalysisExternalComponentResult analysisExternalComponent(String frmJsonSavePath,
                                                                     String parentModuleCode, String relativePath,
                                                                     HashMap<String, Object> externalComponent, String webDevPath) {
        FormDOM json = null;
        Object objUri = null;
        String externalComponentUri = "";
        Object objCode = null;
        String externalComponentCode = "";
        Object objExternalComponentContainerId = null;
        String externalComponentContainerId = "";
        String externalComponentPath = "";
        FormMetadataManager formMetadataManager = new FormMetadataManager(this.executeEnvironment, relativePath, this.isUpgradeTool);
        //TODO: 验证TryGetValue在java中语义实现
        objUri = externalComponent.get("uri");
        externalComponentUri = objUri != null ? objUri.toString() : "";
        objCode = externalComponent.get("code");
        externalComponentCode = objCode != null ? objCode.toString() : "";
        if (externalComponent.containsKey("containerId")) {
            objExternalComponentContainerId = externalComponent.get("containerId");
            externalComponentContainerId = objExternalComponentContainerId.toString();
        }

        boolean useIsolateJs = externalComponent.get("useIsolateJs") != null && (boolean) externalComponent.get("useIsolateJs");

        if (!useIsolateJs && !StringUtility.isNullOrEmpty(externalComponentUri)) {
            // 获取组合表单的元数据信息
            String formMetaDataStr = formMetadataManager.getVisualDom(externalComponentUri, externalComponentCode, StringUtility.getOrDefault(externalComponent.get("name"), ""), StringUtility.getOrDefault(externalComponent.get("nameSpace"), ""));
            json = SerializeUtility.getInstance().deserialize(formMetaDataStr, FormDOM.class);

            if (!StringUtility.isNullOrEmpty(formMetaDataStr)) {
                if (!StringUtility.isNullOrEmpty(externalComponentContainerId) && StringUtility.isStartWithNumber(externalComponentContainerId)) {
                    externalComponentContainerId = "f" + externalComponentContainerId;
                }
                externalComponentPath = !StringUtility.isNullOrEmpty(externalComponentContainerId) ? externalComponentContainerId : externalComponentCode;
                externalComponentPath = externalComponentPath.toLowerCase();
                // 保存独立组件frmJson文件
                if (!StringUtility.isNullOrEmpty(frmJsonSavePath)) {

                    formMetadataManager.saveMetadataFile(FileUtility.combine(frmJsonSavePath, parentModuleCode.toLowerCase(),
                            externalComponentPath), externalComponentCode.toLowerCase() + ".frm.json", formMetaDataStr);

                } else {
                    throw new WebCustomException(I18nExceptionConstant.WEB_FORM_METADATA_ERROR_0009);
                }
            }
        }
        AnalysisExternalComponentResult externalComponentResult = new AnalysisExternalComponentResult();
        externalComponentResult.setJson(json);
        externalComponentResult.setExternalComponentPath(externalComponentPath);
        externalComponentResult.setRelativePath(formMetadataManager.getRelativePath());
        externalComponentResult.setExternalComponentUri(externalComponentUri);
        externalComponentResult.setUseIsolateJs(useIsolateJs);

        return externalComponentResult;
    }
}
